/**
 ******************************************************************************
 * @file           : soft_timer.c
 * @brief          : Software Timer Implementation
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "soft_timer.h"

/* Private variables ---------------------------------------------------------*/
/* Exported functions --------------------------------------------------------*/

/**
 * @brief       初始化定时器
 *
 * @param[in]   timer: 定时器指针
 */
void soft_timer_init(SoftTimer_t *timer)
{
    if (timer == NULL)
    {
        return;
    }
    
    timer->period = 0;
    timer->start_tick = 0;
    timer->mode = TIMER_MODE_ONCE;
    timer->state = TIMER_STATE_STOPPED;
    timer->callback = NULL;
    timer->callback_arg = NULL;
}

/**
 * @brief       配置定时器
 *
 * @param[in]   timer: 定时器指针
 * @param[in]   period_ms: 定时周期（毫秒）
 * @param[in]   mode: 定时器模式
 */
void soft_timer_config(SoftTimer_t *timer, uint32_t period_ms, TimerMode_e mode)
{
    if (timer == NULL)
    {
        return;
    }
    
    timer->period = period_ms;
    timer->mode = mode;
}

/**
 * @brief       设置回调函数
 *
 * @param[in]   timer: 定时器指针
 * @param[in]   callback: 回调函数
 * @param[in]   arg: 回调参数
 */
void soft_timer_set_callback(SoftTimer_t *timer, TimerCallback_f callback, void *arg)
{
    if (timer == NULL)
    {
        return;
    }
    
    timer->callback = callback;
    timer->callback_arg = arg;
}

/**
 * @brief       启动定时器
 *
 * @param[in]   timer: 定时器指针
 */
void soft_timer_start(SoftTimer_t *timer)
{
    if (timer == NULL)
    {
        return;
    }
    
    timer->start_tick = soft_timer_get_tick();
    timer->state = TIMER_STATE_RUNNING;
}

/**
 * @brief       停止定时器
 *
 * @param[in]   timer: 定时器指针
 */
void soft_timer_stop(SoftTimer_t *timer)
{
    if (timer == NULL)
    {
        return;
    }
    
    timer->state = TIMER_STATE_STOPPED;
}

/**
 * @brief       重启定时器
 *
 * @param[in]   timer: 定时器指针
 */
void soft_timer_restart(SoftTimer_t *timer)
{
    if (timer == NULL)
    {
        return;
    }
    
    soft_timer_stop(timer);
    soft_timer_start(timer);
}

/**
 * @brief       检查定时器是否运行
 *
 * @param[in]   timer: 定时器指针
 *
 * @retval      true=运行中, false=已停止
 */
bool soft_timer_is_running(SoftTimer_t *timer)
{
    if (timer == NULL)
    {
        return false;
    }
    
    return (timer->state == TIMER_STATE_RUNNING);
}

/**
 * @brief       检查定时器是否超时
 *
 * @param[in]   timer: 定时器指针
 *
 * @retval      true=已超时, false=未超时
 */
bool soft_timer_is_expired(SoftTimer_t *timer)
{
    uint32_t elapsed;
    
    if (timer == NULL || timer->state != TIMER_STATE_RUNNING)
    {
        return false;
    }
    
    elapsed = soft_timer_get_tick() - timer->start_tick;
    
    return (elapsed >= timer->period);
}

/**
 * @brief       获取剩余时间
 *
 * @param[in]   timer: 定时器指针
 *
 * @retval      剩余时间（ms）
 */
uint32_t soft_timer_remaining(SoftTimer_t *timer)
{
    uint32_t elapsed;
    
    if (timer == NULL || timer->state != TIMER_STATE_RUNNING)
    {
        return 0;
    }
    
    elapsed = soft_timer_get_tick() - timer->start_tick;
    
    if (elapsed >= timer->period)
    {
        return 0;
    }
    
    return (timer->period - elapsed);
}

/**
 * @brief       获取已运行时间
 *
 * @param[in]   timer: 定时器指针
 *
 * @retval      已运行时间（ms）
 */
uint32_t soft_timer_elapsed(SoftTimer_t *timer)
{
    if (timer == NULL || timer->state != TIMER_STATE_RUNNING)
    {
        return 0;
    }
    
    return (soft_timer_get_tick() - timer->start_tick);
}

/**
 * @brief       更新定时器（需在主循环中调用）
 *
 * @param[in]   timer: 定时器指针
 */
void soft_timer_update(SoftTimer_t *timer)
{
    if (timer == NULL || timer->state != TIMER_STATE_RUNNING)
    {
        return;
    }
    
    /* 检查是否超时 */
    if (soft_timer_is_expired(timer))
    {
        /* 调用回调函数 */
        if (timer->callback != NULL)
        {
            timer->callback(timer->callback_arg);
        }
        
        /* 根据模式处理 */
        if (timer->mode == TIMER_MODE_PERIODIC)
        {
            /* 周期模式：重新开始 */
            timer->start_tick = soft_timer_get_tick();
        }
        else
        {
            /* 单次模式：停止 */
            timer->state = TIMER_STATE_EXPIRED;
        }
    }
}

/**
 * @brief       延时（毫秒）
 *
 * @param[in]   ms: 延时时间（毫秒）
 */
void soft_timer_delay_ms(uint32_t ms)
{
    uint32_t start_tick = soft_timer_get_tick();
    
    while ((soft_timer_get_tick() - start_tick) < ms)
    {
        /* 等待 */
    }
}

/**
 * @brief       获取系统滴答（需要用户实现）
 *
 * @note        STM32使用HAL库时，可以这样实现：
 *              uint32_t soft_timer_get_tick(void)
 *              {
 *                  return HAL_GetTick();
 *              }
 *
 * @retval      当前滴答值（ms）
 */
__weak uint32_t soft_timer_get_tick(void)
{
    /* 默认实现：返回0（需要用户重新实现） */
    return 0;
}
